'use strict';

const Subscription = require('egg').Subscription;
const NodeRSA = require('node-rsa');
const uuidv4 = require('uuid/v4');
const moment = require('moment');

// 自动上链
class AutoScain extends Subscription {
  // 通过 schedule 属性来设置定时任务的执行间隔等配置
  static get schedule() {
    return {
      // interval: '1', // 测试的时候用
      // cron: '0 */1 * * * *', // 每一分钟秒执行一次
      interval: '1m', // 1 分钟间隔
      type: 'worker', // 随机单个worker
      disable: false, // 当这个值为true的时候，此定时任务不会执行
    };
  }

  // subscribe 是真正定时任务执行时被运行的函数
  async subscribe() {
    const { ctx, app } = this;
    const resource = 'locks:scain:autonScainEpidemic'; // 锁定的资源名称,这里指锁定上链的事情
    const ttl = 2 * 60 * 1000; // 锁定的时间正式服锁定2分钟
    const RedLock = await ctx.service.lock.redLock.redLockSelf();
    const lock = await new Promise(resolve => {
      RedLock.lock(resource, ttl).then(function(lock) {
        resolve(lock);
      }).catch(e => {
        resolve(false);
      });
    });

    // 如果锁定则释放
    if (lock === false) {
      return;
    }

    // 获取需要上链的数据
    const param = {
      limit: 100,
      where: {
        status: 1,
      },
    };

    const dbresult = await ctx.model.Record.findAll(param)
      .then(data => {
        return { success: true, data };
      }).catch(e => {
        return { success: false, data: e };
      });

    // 判断数量,数量为0则全部都上链完毕
    if (dbresult.data.length === 0) {
      return;
    }

    // 准备需要转账所使用的钱包
    const walletFrom = app.config.SWTC.walletFrom;
    const walletTo = app.config.SWTC.walletTo;

    // 初始化数据结构
    const params = {
      account: walletFrom.address,
      secret: walletFrom.secret,
      rsa: 'false',
      tx: [
      ],
    };

    // map查询的数据
    dbresult.data.map(item => {
      const structure = {
        to: walletTo.address,
        value: '0.00001',
        currency: 'SWT',
        issuer: 'jGa9J9TkqtBcUoHe2zqhVFFbgUVED6o9or',
        addMemo: '',
      };

      let memo = '';

      memo = `id:${item.uuid} `;

      // 加上类型
      if (item.type) {
        memo = `${memo}类型：${ctx.service.record.record.formatType(item.type)} `;
      }

      // 加上发布时间
      if (item.publish_time) {
        memo = `${memo}发布时间：${moment(item.publish_time).format('YYYY-MM-DD')} `;
      }

      // 加上发布方
      if (item.publish_name) {
        memo = `${memo}发布方：${item.publish_name} `;
      }

      // 牌照
      if (item.licence) {
        memo = `${memo}牌照：${item.licence} `;
      }

      // 座位号
      if (item.licence_seat) {
        memo = `${memo}座位：${item.licence_seat} `;
      }

      // 出发时间
      if (item.licence_time) {
        memo = `${memo}出发时间：${moment(item.licence_time).format('YYYY-MM-DD')} `;
      }

      // 出发站点
      if (item.departure) {
        memo = `${memo}出发站点：${item.departure} `;
      }

      // 到达站点
      if (item.arrive) {
        memo = `${memo}到达站点：${item.arrive} `;
      }

      // 省
      if (item.province) {
        memo = `${memo}省：${item.province} `;
      }

      // 市
      if (item.cities) {
        memo = `${memo}市：${item.cities} `;
      }

      // 区
      if (item.area) {
        memo = `${memo}区：${item.area} `;
      }

      // 详细地址
      if (item.address) {
        memo = `${memo}详细地址：${item.address} `;
      }

      // 说明性文字
      if (item.address) {
        memo = `${memo}有确诊肺炎患者 `;
      }


      // 添加完毕，检测长度，超出长度，进行数据精简
      if (!ctx.helper.checkMemoLength(memo)) {
        memo = '';
        memo = `id:${item.uuid} `;

        // 加上类型
        if (item.type) {
          memo = `${memo}类型：${ctx.service.record.record.formatType(item.type)} `;
        }

        // 说明性文字
        if (item.address) {
          memo = `${memo}有确诊肺炎患者 `;
        }
      }

      structure.addMemo = memo;
      params.tx.push(structure);
    });

    // 发送http请求
    const httpResult = await ctx.curl('https://swtclib-app.jingtumzs.com/tx/batch', {
      // 必须指定 method
      method: 'POST',
      // 通过 contentType 告诉 HttpClient 以 JSON 格式发送
      contentType: 'json',
      data: params,
      // 明确告诉 HttpClient 以 JSON 格式处理返回的响应 body
      dataType: 'json',
    }).then(result => {
      return { success: true, data: result };
    }).catch(e => {
      return { success: false, data: e };
    });

    if (httpResult.success === false) {
      this.ctx.logger.info('数据上链，发送请求失败:');
      this.ctx.logger.info(JSON.stringify(httpResult.data));
      return;
    }

    if (httpResult.data.data.success === false) {
      this.ctx.logger.info('数据上链，发送请求失败:');
      this.ctx.logger.info(JSON.stringify(httpResult.data.msg));
      return;
    }

    const httpResponse = httpResult.data.data.data;

    for (const i in dbresult.data) {
      if (httpResponse[i].success === false) {
        break;
      }
      if (httpResponse[i].data && httpResponse[i].data.engine_result === 'tesSUCCESS') {
        const updateData = {
          hash: httpResponse[i].data.hash,
          status: 2,
          is_show: true,
        };

        const updateResult = await ctx.model.Record.update(updateData, {
          where: {
            uuid: dbresult.data[i].uuid,
          } })
          .then(data => {
            return { success: true, data };
          }).catch(e => {
            return { success: false, e };
          });
        if (!updateResult.success) {
          this.ctx.logger.info('数据上链，更新数据库失败。');
          break;
        }
      }
    }

    // 逻辑执行完毕，手动释放锁，无论成功失败，不在执行其他操作
    await new Promise((resolve, reject) => {
      lock.unlock().then(function() {
        resolve(true);
      }).catch(function(err) {
        resolve(false);
      });
    });
  }
}

module.exports = AutoScain;
